
#include <QCoreApplication>
#include <QMetaObject>
#include <QMetaProperty>
#include <QDebug>
#include "myclass.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QObject *obj = new MyClass();
    const QMetaObject *metaObj = obj->metaObject();
    // test 0
    {
        qDebug() << "\n\ntest 0 ...... ";
        int propertyIndex = metaObj->indexOfProperty("text");
        QMetaProperty metaProp = metaObj->property(propertyIndex);
        qDebug() << metaProp.read(obj);
        metaProp.write(obj, "Hello Qt!");
        qDebug() << metaProp.read(obj);

        int retVal;
        QMetaObject::invokeMethod(obj, "printText", Qt::DirectConnection,
                                  Q_RETURN_ARG(int, retVal),
                                  Q_ARG(QString, "test 0: "));
        qDebug() << "retVal: " << retVal;
    }

    // test 1
    {
        qDebug() << "\n\ntest 1 ...... ";
        QObject *obj2 = obj->metaObject()->newInstance(Q_ARG(QObject* , obj));
        const QMetaObject *metaObj2 = obj2->metaObject();
        int propertyIndex2 = metaObj2->indexOfProperty("text");
        QMetaProperty metaProp2 = metaObj2->property(propertyIndex2);
        qDebug() << metaProp2.read(obj2);
        metaProp2.write(obj2, "Hello Qt2!");
        qDebug() << metaProp2.read(obj2);
    }

    // test 2
    {
        qDebug() << "\n\ntest 2 ...... ";
        int methodIndex;
        int methodCount = metaObj->methodCount();
        for(methodIndex = 0; methodIndex < methodCount; ++methodIndex)
        {

            QMetaMethod oneMethod = metaObj->method(methodIndex);
            qDebug() <<"typeName: " <<oneMethod.typeName();
            qDebug() <<"signature: " <<oneMethod.methodSignature();
            qDebug() <<"methodType: " <<oneMethod.methodType();
            qDebug() << "parameterTypes:" << oneMethod.parameterTypes();
            qDebug() <<"parameterNames: " <<oneMethod.parameterNames() <<"\n";
        }
    }

    // test 3
    {
        qDebug() << "\n\ntest 3 ...... ";
        int propertyIndex;
        int propertyCount = metaObj->propertyCount();
        for(propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex)
        {
            QMetaProperty oneProperty =metaObj->property(propertyIndex);
            qDebug() <<"name: " << oneProperty.name();
            qDebug() << "value: " << oneProperty.read(obj);
            qDebug() <<"type: " <<oneProperty.type() <<"\n";
        }
    }

    // test 4
    {
        qDebug() << "\n\ntest 4 ...... ";
        int enumeratorIndex;
        int enumeratorCount = metaObj->enumeratorCount();
        for(enumeratorIndex = 0; enumeratorIndex < enumeratorCount; ++enumeratorIndex)
        {
            QMetaEnum oneEnumerator =metaObj->enumerator(enumeratorIndex);
            int enumIndex;
            int enumCount = oneEnumerator.keyCount();
            for(enumIndex = 0;enumIndex < enumCount; ++enumIndex)
            {
                qDebug() <<oneEnumerator.key(enumIndex) <<" ==> " <<oneEnumerator.value(enumIndex);
            }
        }
    }

    return a.exec();
}
